feat(mcp-core): Add snapshot inspection tools for LLM debugging#935
Conversation
|
A couple of quick thoughts (i didnt read code yet):
|
|
do we need some kind of way to search for snapshots? not sure the workflows |
yes it's gated by their org token, so hopefully that's sufficient
hmm im not familiar with either so i'll have to look into that
right now we're only building out the flow where the LLM knows the exact snapshot in question (ex. CI failure) but yeah that could be a logical next step |
|
@NicoHinderling what do you mean by org token? the gates we have right now basically discover if the account is using a feature. you can prompt your agent to look for it and itll find it - but i believe we lock profiles and some other stuff behind that. its not critical if it uses shared tool definitions, but def valuable if we have no other choice but to expose more tools |
0b08058 to
d4ca3ff
Compare
| | "profile" | ||
| | "snapshot"; | ||
|
|
||
| export interface ResolvedResourceParams { |
There was a problem hiding this comment.
lol never realizaed how fucking ugly codex made this
will clean it up at some point and put in a proper union
|
|
||
| result.hint = `To view a specific image, use get_sentry_resource(url="${resolvedSnapshotUrl}?selectedSnapshot=<image_file_name>").`; | ||
|
|
||
| return JSON.stringify(result, null, 2); |
There was a problem hiding this comment.
do we really feel json is the best output here? we try to curate the responses in most of the MCP so they're useful, vs just being effectively an API proxy
300ed52 to
2a7962a
Compare
…napshots Adds two tools for preprod snapshot support: - `get_latest_base_snapshot` (public): Fetches the most recent base-build snapshot for an app, returning compact image metadata for browsing - `get_snapshot_details` (internal): Returns snapshot comparison summaries with diff info, and fetches specific images when `selectedSnapshot` is provided Snapshot image viewing is consolidated behind `get_sentry_resource` using the `?selectedSnapshot=<image_file_name>` URL pattern from Sentry's UI, avoiding a separate public tool. Also includes: shared `blobToBase64` utility using efficient `Buffer.from()`, snapshot URL parsing with unit tests, `project:read` scope on `get_sentry_resource`, and absolute URL guard in `fetchImageByUrl`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2a7962a to
196881e
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 196881e. Configure here.
| } | ||
|
|
||
| sections.push( | ||
| `\n## Next Steps\n\n- To view a specific image, use \`get_sentry_resource(url="${resolvedSnapshotUrl}?selectedSnapshot=<image_file_name>")\``, |
There was a problem hiding this comment.
Next Steps URL broken when snapshot URL has query params
Low Severity
The "Next Steps" template naively appends ?selectedSnapshot= to resolvedSnapshotUrl. If the input snapshotUrl already contains query parameters (e.g. tracking params or other state from a browser-copied URL), this produces a URL with two ? characters, making it invalid. The second ? needs to be & when query params already exist.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 196881e. Configure here.
| ? ` — file: \`${img.image_file_name}\`` | ||
| : ""; | ||
| sections.push(`- \`${name}\`${group}${file}`); | ||
| } |
There was a problem hiding this comment.
Image formatting logic duplicated across two files
Low Severity
The image line formatting logic (display_name fallback, group suffix, conditional file: annotation) is identically implemented inline in get-latest-base-snapshot.ts and as formatImageLine/getImageDisplayName helpers in get-snapshot-details.ts. These could diverge if one is updated without the other. Extracting to a shared utility (e.g. alongside blobToBase64 in the internal/ directory) would keep them in sync.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 196881e. Configure here.


Summary
Add MCP support for preprod snapshot inspection — LLMs can now browse snapshot builds, view comparison summaries, and fetch specific screenshot images to debug failed CI snapshot tests.
New public tools (+1)
get_latest_base_snapshot— Fetches the most recent base-build snapshot for a given app ID (+ optional branch). Returns compact image metadata (display_name, image_file_name, group) for browsing. Gated behind thepreprodskill.New internal tools (+1)
get_snapshot_details— Routes throughget_sentry_resourcevia URL detection. Two modes:?selectedSnapshot=<image_file_name>is in the URL): Fetches the actual image binary + full metadata, returned asImageContentfor multimodal LLMsHow
get_sentry_resourceroutes snapshotsSnapshot URLs are auto-detected alongside issues, traces, replays, etc:
get_sentry_resource(url="https://sentry.sentry.io/preprod/snapshots/231949/")→ summary + image indexget_sentry_resource(url="https://sentry.sentry.io/preprod/snapshots/231949/?selectedSnapshot=login_screen.png")→ fetches actual imageThis follows the same
?selectedSnapshot=pattern used by Sentry's UI, so URLs copy-pasted from the browser work directly.New API client methods
getSnapshotDetailsGET /api/0/organizations/{org}/preprodartifacts/snapshots/{id}/getSnapshotImageDetailGET /api/0/organizations/{org}/preprodartifacts/snapshots/{id}/images/{identifier}/getLatestBaseSnapshotGET /api/0/organizations/{org}/preprodartifacts/snapshots/latest-base/fetchImageByUrlOther changes
get_sentry_resource: Addedproject:readtorequiredScopes(needed by internal snapshot handler), addedpreprodto skills list, added snapshot URL examples to descriptionparseSentryUrlnow recognizes/preprod/snapshots/{id}/URLs and extracts?selectedSnapshot=query param, with unit testsfetchImageByUrlhardening: Now handles absolutehttps://URLs directly instead of routing throughthis.request()which would prepend the API baseblobToBase64: Extracted tointernal/blob-utils.tsusing efficientBuffer.from().toString("base64"), replacing O(n^2) string concatenation in bothget-snapshot-detailsandget-event-attachmentget_latest_base_snapshotto bothsentry-mcpandsentry-mcp-experimentalagent configsUse cases covered
?selectedSnapshot=-> fetches image directly for visual analysisget_latest_base_snapshotwith app ID -> scans compact index -> views specific images viaget_sentry_resourceTool count
get_latest_base_snapshot), 3 internal tools (+1:get_snapshot_details)